//
//  ClustalW.m
//  iBioCAD
//
//  Created by Orbitus on 10/22/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

#import "ClustalW.h"


@implementation ClustalW

- (void) awakeFromNib
{
	[self init];
}

- (id)init {
    self = [super init];
    [[NSNotificationCenter defaultCenter] addObserver:self 
											selector:@selector(finishedClustal:) 
												name:NSTaskDidTerminateNotification 
											object:nil];
	
	myClustal = nil; // This is a good time to initialize the pointer
	return self;
}

- (IBAction)Clustal:(id)sender
{
	[[NSSound soundNamed:@"Pop"] play];
	[clustalButton setTitle:@"Running..."];
	NSLog(@"Running ClustalW...");
    [clustalButton setEnabled:NO];
	[appRunningIndicator startAnimation:self];
		
	myArguments = [[NSMutableArray alloc] init];
	
	myClustal=[[NSTask alloc] init];
	pipe=[[NSPipe alloc] init];
	NSFileHandle *handle;

	myDesktopFolderPath	=  @"/Sequences/iBioCAD/Desktop/sequence.fasta";
	/*NSString* myOutFilePath = [myDesktopFolderPath stringByAppendingPathComponent:@"Rudy.fasta"];
	
	int i;
	
 	id myString = @"";
	int tempCount;

	
	int ii=0,jj=0;
	/*tempCount = [dnaExportList count];
	
	for (i=0; i < tempCount; i++)
	{
		myString = [myString stringByAppendingString:[[[dnaExportList objectAtIndex:i]  valueForKey:@"title"]  stringByAppendingString:@"\n"] ];
	myString = [myString stringByAppendingString:[[[dnaExportList objectAtIndex:i]  valueForKey:@"sequence"]stringByAppendingString:@"\n"]];
		
		NSLog(@"myString=%@",myString);
	}
	NSLog(@"your String=%@",myString);
	[myString writeToFile:myOutFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
	*/
	
	
	NSString *installLocationFilePath = [[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent]
										 stringByAppendingPathComponent:@"installLocation.txt"];
	id installationLocation = @"";
	id fileManager = [NSFileManager defaultManager];
	
	
	if ( [fileManager fileExistsAtPath:installLocationFilePath isDirectory:NULL] ) {
		installationLocation = [NSString stringWithContentsOfFile:installLocationFilePath];
	}
	
	NSString*	clustalPath	= [installationLocation stringByAppendingString:@"/Applications/EMBOSS-5.0.0/emboss/emma"];
	
	myDesktopFolderPath = [myController desktopFolder];
	
	NSString *mySequencePath = [myDesktopFolderPath stringByAppendingPathComponent:@"sequence.fasta"];
	
	[myClustal setLaunchPath:clustalPath];
	[myClustal setCurrentDirectoryPath:myDesktopFolderPath];
	
	
	[myArguments addObject:@"-sequence"];
	[myArguments addObject:mySequencePath];
	
	[myArguments addObject:@"-outseq"];
	[myArguments addObject:[myDesktopFolderPath stringByAppendingPathComponent:@"emma.fasta"]];
	
	[myArguments addObject:@"-dendoutfile"];
	[myArguments addObject:[myDesktopFolderPath stringByAppendingPathComponent:@"emma.dnd"]];
	
	 
	if([onlyDendrogramFile state])
	 [myArguments addObject:@"-onlydend"];	
	 
	 if([useOldDendrogramFile state])
	 {	
	 [myArguments addObject:@"-dend"];
	 [myArguments addObject:@"-dendfile"];
	 [myArguments addObject:[[dendrogramPath URL] path]];
	 }
	 
	 [myArguments addObject:@"-pwmatrix"];
	 switch ([pwmatrix indexOfSelectedItem]) {
	 case 0:
	 [myArguments addObject:@"b"];
	 break;
	 case 1:
	 [myArguments addObject:@"p"];
	 break;
	 case 2:
	 [myArguments addObject:@"g"];
	 break;
	 case 3:
	 [myArguments addObject:@"i"];
	 break;
	 case 4:
	 [myArguments addObject:@"o"];
	 break;
	 }
	 
	 [myArguments addObject:@"-pwdnamatrix"];
	 switch ([pwmatrix indexOfSelectedItem]) {
	 case 0:
	 [myArguments addObject:@"i"];
	 break;
	 case 1:
	 [myArguments addObject:@"c"];
	 break;
	 case 2:
	 [myArguments addObject:@"o"];
	 break;
	 }
	 
	 BOOL isDirectory = NO;
	 BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:[[pairwiseDataFile URL] path] isDirectory:&isDirectory];
	 if (isDirectory == NO)
	 {
	 [myArguments addObject:@"-pairwisedatafile"];
	 [myArguments addObject:[[pairwiseDataFile URL] path]];
	 }
	 
	 [myArguments addObject:@"-matrix"];
	 switch ([matrix indexOfSelectedItem]) {
	 case 0:
	 [myArguments addObject:@"b"];
	 break;
	 case 1:
	 [myArguments addObject:@"p"];
	 break;
	 case 2:
	 [myArguments addObject:@"g"];
	 break;
	 case 3:
	 [myArguments addObject:@"i"];
	 break;
	 case 4:
	 [myArguments addObject:@"o"];
	 break;
	 }
	 
	 [myArguments addObject:@"-dnamatrix"];
	 switch ([dnamatrix indexOfSelectedItem]) {
	 case 0:
	 [myArguments addObject:@"i"];
	 break;
	 case 1:
	 [myArguments addObject:@"c"];
	 break;
	 case 2:
	 [myArguments addObject:@"o"];
	 break;
	 }
	 
	 isDirectory = NO;
	 exists = [[NSFileManager defaultManager] fileExistsAtPath:[[comparisonMatrixFile URL] path] isDirectory:&isDirectory];
	 if (isDirectory == NO)
	 {
	 [myArguments addObject:@"-mamatrixfile"];
	 [myArguments addObject:[[comparisonMatrixFile URL] path]];
	 }
	 
	 if([slow state])
	 [myArguments addObject:@"-slow"];
	 
	 [myArguments addObject:@"-pwgapopen"];
	 [myArguments addObject:[pwgapopen stringValue]];
	 
	 [myArguments addObject:@"-pwgapextend"];
	 [myArguments addObject:[pwgapextend stringValue]];
	 
	 [myArguments addObject:@"-ktup"];
	 [myArguments addObject:[ktup stringValue]];
	 
	 [myArguments addObject:@"-gapw"];
	 [myArguments addObject:[gapw stringValue]];
	 
	 [myArguments addObject:@"-topdiags"];
	 [myArguments addObject:[topDiags stringValue]];
	 
	 [myArguments addObject:@"-window"];
	 [myArguments addObject:[window stringValue]];
	 
	 if([noPercent state])
	 [myArguments addObject:@"-nopercent"];
	 
	 [myArguments addObject:@"-gapopen"];
	 [myArguments addObject:[gapOpen stringValue]];
	 
	 [myArguments addObject:@"-gapextend"];
	 [myArguments addObject:[gapExtend stringValue]];
	 
	 if([endGaps state])
	 [myArguments addObject:@"-endgaps"];
	 
	 [myArguments addObject:@"-gapdist"];
	 [myArguments addObject:[gapDist stringValue]];
	 
	 if([norgap state])
	 [myArguments addObject:@"-norgap"];
	 
	 [myArguments addObject:@"-hgapres"];
	 [myArguments addObject:[hgapres stringValue]];
	 
	 if([nohgap state])
	 [myArguments addObject:@"-nohgap"];
	 
	 [myArguments addObject:@"-maxdiv"];
	 [myArguments addObject:[maxDiv stringValue]];
	
	[clustalOutput setString:@"Starting ClustalW Alignment...\n"];
	
	[clustalOutput setString:[[clustalOutput string] stringByAppendingString: [[myArguments description] stringByReplacingOccurrencesOfString:@"\n" withString:@""]]];
	
//	[myClustal setArguments:[NSArray arrayWithObjects:@"-sequence", mySequencePath ,@"-outseq", [myDesktopFolderPath stringByAppendingPathComponent:@"emma.fasta"], @"-dendoutfile", [myDesktopFolderPath stringByAppendingPathComponent:@"emma.dnd"], nil]];
	[myClustal setArguments:myArguments];
	
	[myClustal setStandardOutput:pipe];
	
	
	handle=[pipe fileHandleForReading];
	
	[myClustal launch];
	
	[NSThread detachNewThreadSelector:@selector(copyData:)
								 toTarget:self withObject:handle];
	

	
}
- (void)copyData:(NSFileHandle*)handle {
    NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
   NSData *data;
    while([data=[handle availableData] length]) { // until EOF (check reference)
        NSString *string=[[NSString alloc] initWithData:data
																				encoding:NSASCIIStringEncoding];
        NSRange theEnd=NSMakeRange([[clustalOutput string] length],0);
		
        [clustalOutput replaceCharactersInRange:theEnd
														   withString:string]; // append new string to the end
        theEnd.location+=[string length]; // the end has moved
        [clustalOutput scrollRangeToVisible:theEnd];
		
        [string release];
    }
	[NSThread detachNewThreadSelector:@selector(finishedClustal:)
							 toTarget:self withObject:nil];
    [pool release];
}

- (void)finishedClustal:(NSNotification *)aNotification {
	NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];

	NSLog(@"`...Finished ClustalW!");
	[clustalButton setTitle:@"ClustalW"];
	[clustalButton setEnabled:YES];
	[appRunningIndicator stopAnimation:self];
	
	int status = [myClustal terminationStatus]; 
	
	if (status == 1) 
	{
		NSLog(@"Task succeeded."); 
		[[NSSound soundNamed:@"Ping"] play];
	}
	else 
	{	
		NSLog(@"Task failed."); 
		[[NSSound soundNamed:@"Pop"] play];
	}
	
	
	NSLog(@"Clustal Alignment Complete");
	
	
	[myClustal release]; // Don't forget to clean up memory
    [pipe release];
	[pool release];

}

@end
